package com.jack.payment.aspect;


import com.jack.payment.aspect.common.AspectHandlerUtil;
import com.jack.payment.entity.business.UriDescribeBo;
import com.jack.payment.entity.common.BusinessException;
import com.jack.payment.entity.common.CommonResult;
import com.jack.payment.entity.common.PayCallParam;
import com.jack.payment.entity.mong.RequestLogModel;
import com.jack.payment.rabbitmq.RabbitQueueSendUtil;
import com.jack.payment.service.basic.impl.UserSettingServiceImpl;
import com.jack.payment.util.network.NetworkUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;

@Aspect
@Component
public class ResultApiAspect{
    private Logger log = LoggerFactory.getLogger(ResultApiAspect.class);

    @Autowired
    private AspectHandlerUtil aspectHandler;
    @Autowired
    private UserSettingServiceImpl userSettingService;
    @Autowired
    private RabbitQueueSendUtil rabbitQueueSendUtil;

    @Pointcut("execution(* com.jack.payment.controller.api..*(..))")
    public void executeApiService() {
    }

    @Around("executeApiService()")
    public CommonResult doAround(ProceedingJoinPoint pjp) throws Throwable{
        //接口请求开始时间
        Long startRequestTime = System.currentTimeMillis();
        // 获取请求数据
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取类包名
        String pageName = pjp.getTarget().getClass().getPackage().getName();
        // 方法获取方法名
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        // api 接口
        String uri = request.getRequestURI();
        // 获取请求参数
        Object[] args = pjp.getArgs();
        // 返回值
        CommonResult resultParam = new CommonResult();
        // 请求数据
        PayCallParam param = new PayCallParam();
        // 请求uri 地址说明
        UriDescribeBo uriDescribeModel = new UriDescribeBo(uri, "未知的接口");
        String message = "";
        Integer status = 0;
        try {
            uriDescribeModel = aspectHandler.getUriDetail(method, uri);
            param = (PayCallParam) args[0];
            param.setApiKey(userSettingService.getAppointUserApiKey(String.valueOf(param.getApiKey()), 1));
            args[0] = param;
            resultParam = (CommonResult) pjp.proceed(args);
        } catch (Exception e) {
            resultParam = aspectHandler.exceptionClassJudgeVerify(uri, e);
            message = resultParam.getMessage();
            status = 0;
        } finally {

            sendApiRequestToQueueMessage(
                    startRequestTime, uriDescribeModel,
                    request, args, status, param, message
                    );
        }
        return resultParam;
    }

    /**
     *  发送消息队列
     */
    public void sendApiRequestToQueueMessage(Long startTime,
                                             UriDescribeBo uriDescribeBo,
                                             HttpServletRequest request,
                                             Object[] args, Integer status,
                                             PayCallParam param, String message) {
        String requestIp = NetworkUtil.getIPAddress(request);
        RequestLogModel requestLogModel = aspectHandler.builderRequestLogModel(3, startTime, uriDescribeBo,
                request, args, requestIp, status, message);
        try {
            rabbitQueueSendUtil.requestLogQueueMessage(requestLogModel);
        } catch (BusinessException e) {
            log.error("消息队列发送失败!!! " + e);
        }
    }
}
